{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Ames数据预处理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 导入必要的工具包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 数据读取及基本处理\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "# 查看数据分布是否对称/计算斜度\n",
    "from scipy.stats import skew\n",
    "\n",
    "# 可视化\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "from IPython.display import display\n",
    "# 自定义\n",
    "pd.set_option('display.float_format', lambda x: '%.3f' % x)\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读入数据\n",
    "将训练数据和测试数据一起读入"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Id</th>\n",
       "      <th>MSSubClass</th>\n",
       "      <th>MSZoning</th>\n",
       "      <th>LotFrontage</th>\n",
       "      <th>LotArea</th>\n",
       "      <th>Street</th>\n",
       "      <th>Alley</th>\n",
       "      <th>LotShape</th>\n",
       "      <th>LandContour</th>\n",
       "      <th>Utilities</th>\n",
       "      <th>...</th>\n",
       "      <th>PoolArea</th>\n",
       "      <th>PoolQC</th>\n",
       "      <th>Fence</th>\n",
       "      <th>MiscFeature</th>\n",
       "      <th>MiscVal</th>\n",
       "      <th>MoSold</th>\n",
       "      <th>YrSold</th>\n",
       "      <th>SaleType</th>\n",
       "      <th>SaleCondition</th>\n",
       "      <th>SalePrice</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>60</td>\n",
       "      <td>RL</td>\n",
       "      <td>65.000</td>\n",
       "      <td>8450</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Reg</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>2008</td>\n",
       "      <td>WD</td>\n",
       "      <td>Normal</td>\n",
       "      <td>208500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>20</td>\n",
       "      <td>RL</td>\n",
       "      <td>80.000</td>\n",
       "      <td>9600</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Reg</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>5</td>\n",
       "      <td>2007</td>\n",
       "      <td>WD</td>\n",
       "      <td>Normal</td>\n",
       "      <td>181500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>60</td>\n",
       "      <td>RL</td>\n",
       "      <td>68.000</td>\n",
       "      <td>11250</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>IR1</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "      <td>2008</td>\n",
       "      <td>WD</td>\n",
       "      <td>Normal</td>\n",
       "      <td>223500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>70</td>\n",
       "      <td>RL</td>\n",
       "      <td>60.000</td>\n",
       "      <td>9550</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>IR1</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>2006</td>\n",
       "      <td>WD</td>\n",
       "      <td>Abnorml</td>\n",
       "      <td>140000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>60</td>\n",
       "      <td>RL</td>\n",
       "      <td>84.000</td>\n",
       "      <td>14260</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>IR1</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>12</td>\n",
       "      <td>2008</td>\n",
       "      <td>WD</td>\n",
       "      <td>Normal</td>\n",
       "      <td>250000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 81 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   Id  MSSubClass MSZoning  LotFrontage  LotArea Street Alley LotShape  \\\n",
       "0   1          60       RL       65.000     8450   Pave   NaN      Reg   \n",
       "1   2          20       RL       80.000     9600   Pave   NaN      Reg   \n",
       "2   3          60       RL       68.000    11250   Pave   NaN      IR1   \n",
       "3   4          70       RL       60.000     9550   Pave   NaN      IR1   \n",
       "4   5          60       RL       84.000    14260   Pave   NaN      IR1   \n",
       "\n",
       "  LandContour Utilities    ...     PoolArea PoolQC Fence MiscFeature MiscVal  \\\n",
       "0         Lvl    AllPub    ...            0    NaN   NaN         NaN       0   \n",
       "1         Lvl    AllPub    ...            0    NaN   NaN         NaN       0   \n",
       "2         Lvl    AllPub    ...            0    NaN   NaN         NaN       0   \n",
       "3         Lvl    AllPub    ...            0    NaN   NaN         NaN       0   \n",
       "4         Lvl    AllPub    ...            0    NaN   NaN         NaN       0   \n",
       "\n",
       "  MoSold YrSold  SaleType  SaleCondition  SalePrice  \n",
       "0      2   2008        WD         Normal     208500  \n",
       "1      5   2007        WD         Normal     181500  \n",
       "2      9   2008        WD         Normal     223500  \n",
       "3      2   2006        WD        Abnorml     140000  \n",
       "4     12   2008        WD         Normal     250000  \n",
       "\n",
       "[5 rows x 81 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读入训练集数据\n",
    "train = pd.read_csv(\"/Users/qi/PycharmProjects/HousePrices/Ames_House_train.csv\")\n",
    "# 通过观察前5行，了解每列（特征）的概况\n",
    "train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "train: (1460, 81)\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1460 entries, 0 to 1459\n",
      "Data columns (total 81 columns):\n",
      "Id               1460 non-null int64\n",
      "MSSubClass       1460 non-null int64\n",
      "MSZoning         1460 non-null object\n",
      "LotFrontage      1201 non-null float64\n",
      "LotArea          1460 non-null int64\n",
      "Street           1460 non-null object\n",
      "Alley            91 non-null object\n",
      "LotShape         1460 non-null object\n",
      "LandContour      1460 non-null object\n",
      "Utilities        1460 non-null object\n",
      "LotConfig        1460 non-null object\n",
      "LandSlope        1460 non-null object\n",
      "Neighborhood     1460 non-null object\n",
      "Condition1       1460 non-null object\n",
      "Condition2       1460 non-null object\n",
      "BldgType         1460 non-null object\n",
      "HouseStyle       1460 non-null object\n",
      "OverallQual      1460 non-null int64\n",
      "OverallCond      1460 non-null int64\n",
      "YearBuilt        1460 non-null int64\n",
      "YearRemodAdd     1460 non-null int64\n",
      "RoofStyle        1460 non-null object\n",
      "RoofMatl         1460 non-null object\n",
      "Exterior1st      1460 non-null object\n",
      "Exterior2nd      1460 non-null object\n",
      "MasVnrType       1452 non-null object\n",
      "MasVnrArea       1452 non-null float64\n",
      "ExterQual        1460 non-null object\n",
      "ExterCond        1460 non-null object\n",
      "Foundation       1460 non-null object\n",
      "BsmtQual         1423 non-null object\n",
      "BsmtCond         1423 non-null object\n",
      "BsmtExposure     1422 non-null object\n",
      "BsmtFinType1     1423 non-null object\n",
      "BsmtFinSF1       1460 non-null int64\n",
      "BsmtFinType2     1422 non-null object\n",
      "BsmtFinSF2       1460 non-null int64\n",
      "BsmtUnfSF        1460 non-null int64\n",
      "TotalBsmtSF      1460 non-null int64\n",
      "Heating          1460 non-null object\n",
      "HeatingQC        1460 non-null object\n",
      "CentralAir       1460 non-null object\n",
      "Electrical       1459 non-null object\n",
      "1stFlrSF         1460 non-null int64\n",
      "2ndFlrSF         1460 non-null int64\n",
      "LowQualFinSF     1460 non-null int64\n",
      "GrLivArea        1460 non-null int64\n",
      "BsmtFullBath     1460 non-null int64\n",
      "BsmtHalfBath     1460 non-null int64\n",
      "FullBath         1460 non-null int64\n",
      "HalfBath         1460 non-null int64\n",
      "BedroomAbvGr     1460 non-null int64\n",
      "KitchenAbvGr     1460 non-null int64\n",
      "KitchenQual      1460 non-null object\n",
      "TotRmsAbvGrd     1460 non-null int64\n",
      "Functional       1460 non-null object\n",
      "Fireplaces       1460 non-null int64\n",
      "FireplaceQu      770 non-null object\n",
      "GarageType       1379 non-null object\n",
      "GarageYrBlt      1379 non-null float64\n",
      "GarageFinish     1379 non-null object\n",
      "GarageCars       1460 non-null int64\n",
      "GarageArea       1460 non-null int64\n",
      "GarageQual       1379 non-null object\n",
      "GarageCond       1379 non-null object\n",
      "PavedDrive       1460 non-null object\n",
      "WoodDeckSF       1460 non-null int64\n",
      "OpenPorchSF      1460 non-null int64\n",
      "EnclosedPorch    1460 non-null int64\n",
      "3SsnPorch        1460 non-null int64\n",
      "ScreenPorch      1460 non-null int64\n",
      "PoolArea         1460 non-null int64\n",
      "PoolQC           7 non-null object\n",
      "Fence            281 non-null object\n",
      "MiscFeature      54 non-null object\n",
      "MiscVal          1460 non-null int64\n",
      "MoSold           1460 non-null int64\n",
      "YrSold           1460 non-null int64\n",
      "SaleType         1460 non-null object\n",
      "SaleCondition    1460 non-null object\n",
      "SalePrice        1460 non-null int64\n",
      "dtypes: float64(3), int64(35), object(43)\n",
      "memory usage: 924.0+ KB\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Index(['LotFrontage', 'Alley', 'MasVnrType', 'MasVnrArea', 'BsmtQual',\n",
       "       'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinType2',\n",
       "       'Electrical', 'FireplaceQu', 'GarageType', 'GarageYrBlt',\n",
       "       'GarageFinish', 'GarageQual', 'GarageCond', 'PoolQC', 'Fence',\n",
       "       'MiscFeature'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 查看样本个数和特征数\n",
    "print(\"train: \" + str(train.shape))\n",
    "# 查看特征值类型\n",
    "train.info()\n",
    "# 查看哪些特征值有缺失\n",
    "train.columns[train.isnull().sum()>0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 读入测试集数据\n",
    "test = pd.read_csv(\"/Users/qi/PycharmProjects/HousePrices/Ames_House_test.csv\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据探索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Id</th>\n",
       "      <th>MSSubClass</th>\n",
       "      <th>LotFrontage</th>\n",
       "      <th>LotArea</th>\n",
       "      <th>OverallQual</th>\n",
       "      <th>OverallCond</th>\n",
       "      <th>YearBuilt</th>\n",
       "      <th>YearRemodAdd</th>\n",
       "      <th>MasVnrArea</th>\n",
       "      <th>BsmtFinSF1</th>\n",
       "      <th>...</th>\n",
       "      <th>WoodDeckSF</th>\n",
       "      <th>OpenPorchSF</th>\n",
       "      <th>EnclosedPorch</th>\n",
       "      <th>3SsnPorch</th>\n",
       "      <th>ScreenPorch</th>\n",
       "      <th>PoolArea</th>\n",
       "      <th>MiscVal</th>\n",
       "      <th>MoSold</th>\n",
       "      <th>YrSold</th>\n",
       "      <th>SalePrice</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1201.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1452.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>...</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "      <td>1460.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>730.500</td>\n",
       "      <td>56.897</td>\n",
       "      <td>70.050</td>\n",
       "      <td>10516.828</td>\n",
       "      <td>6.099</td>\n",
       "      <td>5.575</td>\n",
       "      <td>1971.268</td>\n",
       "      <td>1984.866</td>\n",
       "      <td>103.685</td>\n",
       "      <td>443.640</td>\n",
       "      <td>...</td>\n",
       "      <td>94.245</td>\n",
       "      <td>46.660</td>\n",
       "      <td>21.954</td>\n",
       "      <td>3.410</td>\n",
       "      <td>15.061</td>\n",
       "      <td>2.759</td>\n",
       "      <td>43.489</td>\n",
       "      <td>6.322</td>\n",
       "      <td>2007.816</td>\n",
       "      <td>180921.196</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>421.610</td>\n",
       "      <td>42.301</td>\n",
       "      <td>24.285</td>\n",
       "      <td>9981.265</td>\n",
       "      <td>1.383</td>\n",
       "      <td>1.113</td>\n",
       "      <td>30.203</td>\n",
       "      <td>20.645</td>\n",
       "      <td>181.066</td>\n",
       "      <td>456.098</td>\n",
       "      <td>...</td>\n",
       "      <td>125.339</td>\n",
       "      <td>66.256</td>\n",
       "      <td>61.119</td>\n",
       "      <td>29.317</td>\n",
       "      <td>55.757</td>\n",
       "      <td>40.177</td>\n",
       "      <td>496.123</td>\n",
       "      <td>2.704</td>\n",
       "      <td>1.328</td>\n",
       "      <td>79442.503</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>1.000</td>\n",
       "      <td>20.000</td>\n",
       "      <td>21.000</td>\n",
       "      <td>1300.000</td>\n",
       "      <td>1.000</td>\n",
       "      <td>1.000</td>\n",
       "      <td>1872.000</td>\n",
       "      <td>1950.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>1.000</td>\n",
       "      <td>2006.000</td>\n",
       "      <td>34900.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>365.750</td>\n",
       "      <td>20.000</td>\n",
       "      <td>59.000</td>\n",
       "      <td>7553.500</td>\n",
       "      <td>5.000</td>\n",
       "      <td>5.000</td>\n",
       "      <td>1954.000</td>\n",
       "      <td>1967.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>5.000</td>\n",
       "      <td>2007.000</td>\n",
       "      <td>129975.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>730.500</td>\n",
       "      <td>50.000</td>\n",
       "      <td>69.000</td>\n",
       "      <td>9478.500</td>\n",
       "      <td>6.000</td>\n",
       "      <td>5.000</td>\n",
       "      <td>1973.000</td>\n",
       "      <td>1994.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>383.500</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000</td>\n",
       "      <td>25.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>6.000</td>\n",
       "      <td>2008.000</td>\n",
       "      <td>163000.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>1095.250</td>\n",
       "      <td>70.000</td>\n",
       "      <td>80.000</td>\n",
       "      <td>11601.500</td>\n",
       "      <td>7.000</td>\n",
       "      <td>6.000</td>\n",
       "      <td>2000.000</td>\n",
       "      <td>2004.000</td>\n",
       "      <td>166.000</td>\n",
       "      <td>712.250</td>\n",
       "      <td>...</td>\n",
       "      <td>168.000</td>\n",
       "      <td>68.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.000</td>\n",
       "      <td>8.000</td>\n",
       "      <td>2009.000</td>\n",
       "      <td>214000.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>1460.000</td>\n",
       "      <td>190.000</td>\n",
       "      <td>313.000</td>\n",
       "      <td>215245.000</td>\n",
       "      <td>10.000</td>\n",
       "      <td>9.000</td>\n",
       "      <td>2010.000</td>\n",
       "      <td>2010.000</td>\n",
       "      <td>1600.000</td>\n",
       "      <td>5644.000</td>\n",
       "      <td>...</td>\n",
       "      <td>857.000</td>\n",
       "      <td>547.000</td>\n",
       "      <td>552.000</td>\n",
       "      <td>508.000</td>\n",
       "      <td>480.000</td>\n",
       "      <td>738.000</td>\n",
       "      <td>15500.000</td>\n",
       "      <td>12.000</td>\n",
       "      <td>2010.000</td>\n",
       "      <td>755000.000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>8 rows × 38 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "            Id  MSSubClass  LotFrontage    LotArea  OverallQual  OverallCond  \\\n",
       "count 1460.000    1460.000     1201.000   1460.000     1460.000     1460.000   \n",
       "mean   730.500      56.897       70.050  10516.828        6.099        5.575   \n",
       "std    421.610      42.301       24.285   9981.265        1.383        1.113   \n",
       "min      1.000      20.000       21.000   1300.000        1.000        1.000   \n",
       "25%    365.750      20.000       59.000   7553.500        5.000        5.000   \n",
       "50%    730.500      50.000       69.000   9478.500        6.000        5.000   \n",
       "75%   1095.250      70.000       80.000  11601.500        7.000        6.000   \n",
       "max   1460.000     190.000      313.000 215245.000       10.000        9.000   \n",
       "\n",
       "       YearBuilt  YearRemodAdd  MasVnrArea  BsmtFinSF1    ...      WoodDeckSF  \\\n",
       "count   1460.000      1460.000    1452.000    1460.000    ...        1460.000   \n",
       "mean    1971.268      1984.866     103.685     443.640    ...          94.245   \n",
       "std       30.203        20.645     181.066     456.098    ...         125.339   \n",
       "min     1872.000      1950.000       0.000       0.000    ...           0.000   \n",
       "25%     1954.000      1967.000       0.000       0.000    ...           0.000   \n",
       "50%     1973.000      1994.000       0.000     383.500    ...           0.000   \n",
       "75%     2000.000      2004.000     166.000     712.250    ...         168.000   \n",
       "max     2010.000      2010.000    1600.000    5644.000    ...         857.000   \n",
       "\n",
       "       OpenPorchSF  EnclosedPorch  3SsnPorch  ScreenPorch  PoolArea   MiscVal  \\\n",
       "count     1460.000       1460.000   1460.000     1460.000  1460.000  1460.000   \n",
       "mean        46.660         21.954      3.410       15.061     2.759    43.489   \n",
       "std         66.256         61.119     29.317       55.757    40.177   496.123   \n",
       "min          0.000          0.000      0.000        0.000     0.000     0.000   \n",
       "25%          0.000          0.000      0.000        0.000     0.000     0.000   \n",
       "50%         25.000          0.000      0.000        0.000     0.000     0.000   \n",
       "75%         68.000          0.000      0.000        0.000     0.000     0.000   \n",
       "max        547.000        552.000    508.000      480.000   738.000 15500.000   \n",
       "\n",
       "        MoSold   YrSold  SalePrice  \n",
       "count 1460.000 1460.000   1460.000  \n",
       "mean     6.322 2007.816 180921.196  \n",
       "std      2.704    1.328  79442.503  \n",
       "min      1.000 2006.000  34900.000  \n",
       "25%      5.000 2007.000 129975.000  \n",
       "50%      6.000 2008.000 163000.000  \n",
       "75%      8.000 2009.000 214000.000  \n",
       "max     12.000 2010.000 755000.000  \n",
       "\n",
       "[8 rows x 38 columns]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对数值型特征，用常用统计量观察其分布\n",
    "train.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "MSZoning 属性的不同取值和出现的次数：\n",
      "RL         1151\n",
      "RM          218\n",
      "FV           65\n",
      "RH           16\n",
      "C (all)      10\n",
      "Name: MSZoning, dtype: int64\n",
      "\n",
      "Street 属性的不同取值和出现的次数：\n",
      "Pave    1454\n",
      "Grvl       6\n",
      "Name: Street, dtype: int64\n",
      "\n",
      "Alley 属性的不同取值和出现的次数：\n",
      "Grvl    50\n",
      "Pave    41\n",
      "Name: Alley, dtype: int64\n",
      "\n",
      "LotShape 属性的不同取值和出现的次数：\n",
      "Reg    925\n",
      "IR1    484\n",
      "IR2     41\n",
      "IR3     10\n",
      "Name: LotShape, dtype: int64\n",
      "\n",
      "LandContour 属性的不同取值和出现的次数：\n",
      "Lvl    1311\n",
      "Bnk      63\n",
      "HLS      50\n",
      "Low      36\n",
      "Name: LandContour, dtype: int64\n",
      "\n",
      "Utilities 属性的不同取值和出现的次数：\n",
      "AllPub    1459\n",
      "NoSeWa       1\n",
      "Name: Utilities, dtype: int64\n",
      "\n",
      "LotConfig 属性的不同取值和出现的次数：\n",
      "Inside     1052\n",
      "Corner      263\n",
      "CulDSac      94\n",
      "FR2          47\n",
      "FR3           4\n",
      "Name: LotConfig, dtype: int64\n",
      "\n",
      "LandSlope 属性的不同取值和出现的次数：\n",
      "Gtl    1382\n",
      "Mod      65\n",
      "Sev      13\n",
      "Name: LandSlope, dtype: int64\n",
      "\n",
      "Neighborhood 属性的不同取值和出现的次数：\n",
      "NAmes      225\n",
      "CollgCr    150\n",
      "OldTown    113\n",
      "Edwards    100\n",
      "Somerst     86\n",
      "Gilbert     79\n",
      "NridgHt     77\n",
      "Sawyer      74\n",
      "NWAmes      73\n",
      "SawyerW     59\n",
      "BrkSide     58\n",
      "Crawfor     51\n",
      "Mitchel     49\n",
      "NoRidge     41\n",
      "Timber      38\n",
      "IDOTRR      37\n",
      "ClearCr     28\n",
      "StoneBr     25\n",
      "SWISU       25\n",
      "Blmngtn     17\n",
      "MeadowV     17\n",
      "BrDale      16\n",
      "Veenker     11\n",
      "NPkVill      9\n",
      "Blueste      2\n",
      "Name: Neighborhood, dtype: int64\n",
      "\n",
      "Condition1 属性的不同取值和出现的次数：\n",
      "Norm      1260\n",
      "Feedr       81\n",
      "Artery      48\n",
      "RRAn        26\n",
      "PosN        19\n",
      "RRAe        11\n",
      "PosA         8\n",
      "RRNn         5\n",
      "RRNe         2\n",
      "Name: Condition1, dtype: int64\n",
      "\n",
      "Condition2 属性的不同取值和出现的次数：\n",
      "Norm      1445\n",
      "Feedr        6\n",
      "RRNn         2\n",
      "Artery       2\n",
      "PosN         2\n",
      "PosA         1\n",
      "RRAe         1\n",
      "RRAn         1\n",
      "Name: Condition2, dtype: int64\n",
      "\n",
      "BldgType 属性的不同取值和出现的次数：\n",
      "1Fam      1220\n",
      "TwnhsE     114\n",
      "Duplex      52\n",
      "Twnhs       43\n",
      "2fmCon      31\n",
      "Name: BldgType, dtype: int64\n",
      "\n",
      "HouseStyle 属性的不同取值和出现的次数：\n",
      "1Story    726\n",
      "2Story    445\n",
      "1.5Fin    154\n",
      "SLvl       65\n",
      "SFoyer     37\n",
      "1.5Unf     14\n",
      "2.5Unf     11\n",
      "2.5Fin      8\n",
      "Name: HouseStyle, dtype: int64\n",
      "\n",
      "RoofStyle 属性的不同取值和出现的次数：\n",
      "Gable      1141\n",
      "Hip         286\n",
      "Flat         13\n",
      "Gambrel      11\n",
      "Mansard       7\n",
      "Shed          2\n",
      "Name: RoofStyle, dtype: int64\n",
      "\n",
      "RoofMatl 属性的不同取值和出现的次数：\n",
      "CompShg    1434\n",
      "Tar&Grv      11\n",
      "WdShngl       6\n",
      "WdShake       5\n",
      "Membran       1\n",
      "ClyTile       1\n",
      "Roll          1\n",
      "Metal         1\n",
      "Name: RoofMatl, dtype: int64\n",
      "\n",
      "Exterior1st 属性的不同取值和出现的次数：\n",
      "VinylSd    515\n",
      "HdBoard    222\n",
      "MetalSd    220\n",
      "Wd Sdng    206\n",
      "Plywood    108\n",
      "CemntBd     61\n",
      "BrkFace     50\n",
      "WdShing     26\n",
      "Stucco      25\n",
      "AsbShng     20\n",
      "BrkComm      2\n",
      "Stone        2\n",
      "ImStucc      1\n",
      "AsphShn      1\n",
      "CBlock       1\n",
      "Name: Exterior1st, dtype: int64\n",
      "\n",
      "Exterior2nd 属性的不同取值和出现的次数：\n",
      "VinylSd    504\n",
      "MetalSd    214\n",
      "HdBoard    207\n",
      "Wd Sdng    197\n",
      "Plywood    142\n",
      "CmentBd     60\n",
      "Wd Shng     38\n",
      "Stucco      26\n",
      "BrkFace     25\n",
      "AsbShng     20\n",
      "ImStucc     10\n",
      "Brk Cmn      7\n",
      "Stone        5\n",
      "AsphShn      3\n",
      "Other        1\n",
      "CBlock       1\n",
      "Name: Exterior2nd, dtype: int64\n",
      "\n",
      "MasVnrType 属性的不同取值和出现的次数：\n",
      "None       864\n",
      "BrkFace    445\n",
      "Stone      128\n",
      "BrkCmn      15\n",
      "Name: MasVnrType, dtype: int64\n",
      "\n",
      "ExterQual 属性的不同取值和出现的次数：\n",
      "TA    906\n",
      "Gd    488\n",
      "Ex     52\n",
      "Fa     14\n",
      "Name: ExterQual, dtype: int64\n",
      "\n",
      "ExterCond 属性的不同取值和出现的次数：\n",
      "TA    1282\n",
      "Gd     146\n",
      "Fa      28\n",
      "Ex       3\n",
      "Po       1\n",
      "Name: ExterCond, dtype: int64\n",
      "\n",
      "Foundation 属性的不同取值和出现的次数：\n",
      "PConc     647\n",
      "CBlock    634\n",
      "BrkTil    146\n",
      "Slab       24\n",
      "Stone       6\n",
      "Wood        3\n",
      "Name: Foundation, dtype: int64\n",
      "\n",
      "BsmtQual 属性的不同取值和出现的次数：\n",
      "TA    649\n",
      "Gd    618\n",
      "Ex    121\n",
      "Fa     35\n",
      "Name: BsmtQual, dtype: int64\n",
      "\n",
      "BsmtCond 属性的不同取值和出现的次数：\n",
      "TA    1311\n",
      "Gd      65\n",
      "Fa      45\n",
      "Po       2\n",
      "Name: BsmtCond, dtype: int64\n",
      "\n",
      "BsmtExposure 属性的不同取值和出现的次数：\n",
      "No    953\n",
      "Av    221\n",
      "Gd    134\n",
      "Mn    114\n",
      "Name: BsmtExposure, dtype: int64\n",
      "\n",
      "BsmtFinType1 属性的不同取值和出现的次数：\n",
      "Unf    430\n",
      "GLQ    418\n",
      "ALQ    220\n",
      "BLQ    148\n",
      "Rec    133\n",
      "LwQ     74\n",
      "Name: BsmtFinType1, dtype: int64\n",
      "\n",
      "BsmtFinType2 属性的不同取值和出现的次数：\n",
      "Unf    1256\n",
      "Rec      54\n",
      "LwQ      46\n",
      "BLQ      33\n",
      "ALQ      19\n",
      "GLQ      14\n",
      "Name: BsmtFinType2, dtype: int64\n",
      "\n",
      "Heating 属性的不同取值和出现的次数：\n",
      "GasA     1428\n",
      "GasW       18\n",
      "Grav        7\n",
      "Wall        4\n",
      "OthW        2\n",
      "Floor       1\n",
      "Name: Heating, dtype: int64\n",
      "\n",
      "HeatingQC 属性的不同取值和出现的次数：\n",
      "Ex    741\n",
      "TA    428\n",
      "Gd    241\n",
      "Fa     49\n",
      "Po      1\n",
      "Name: HeatingQC, dtype: int64\n",
      "\n",
      "CentralAir 属性的不同取值和出现的次数：\n",
      "Y    1365\n",
      "N      95\n",
      "Name: CentralAir, dtype: int64\n",
      "\n",
      "Electrical 属性的不同取值和出现的次数：\n",
      "SBrkr    1334\n",
      "FuseA      94\n",
      "FuseF      27\n",
      "FuseP       3\n",
      "Mix         1\n",
      "Name: Electrical, dtype: int64\n",
      "\n",
      "KitchenQual 属性的不同取值和出现的次数：\n",
      "TA    735\n",
      "Gd    586\n",
      "Ex    100\n",
      "Fa     39\n",
      "Name: KitchenQual, dtype: int64\n",
      "\n",
      "Functional 属性的不同取值和出现的次数：\n",
      "Typ     1360\n",
      "Min2      34\n",
      "Min1      31\n",
      "Mod       15\n",
      "Maj1      14\n",
      "Maj2       5\n",
      "Sev        1\n",
      "Name: Functional, dtype: int64\n",
      "\n",
      "FireplaceQu 属性的不同取值和出现的次数：\n",
      "Gd    380\n",
      "TA    313\n",
      "Fa     33\n",
      "Ex     24\n",
      "Po     20\n",
      "Name: FireplaceQu, dtype: int64\n",
      "\n",
      "GarageType 属性的不同取值和出现的次数：\n",
      "Attchd     870\n",
      "Detchd     387\n",
      "BuiltIn     88\n",
      "Basment     19\n",
      "CarPort      9\n",
      "2Types       6\n",
      "Name: GarageType, dtype: int64\n",
      "\n",
      "GarageFinish 属性的不同取值和出现的次数：\n",
      "Unf    605\n",
      "RFn    422\n",
      "Fin    352\n",
      "Name: GarageFinish, dtype: int64\n",
      "\n",
      "GarageQual 属性的不同取值和出现的次数：\n",
      "TA    1311\n",
      "Fa      48\n",
      "Gd      14\n",
      "Ex       3\n",
      "Po       3\n",
      "Name: GarageQual, dtype: int64\n",
      "\n",
      "GarageCond 属性的不同取值和出现的次数：\n",
      "TA    1326\n",
      "Fa      35\n",
      "Gd       9\n",
      "Po       7\n",
      "Ex       2\n",
      "Name: GarageCond, dtype: int64\n",
      "\n",
      "PavedDrive 属性的不同取值和出现的次数：\n",
      "Y    1340\n",
      "N      90\n",
      "P      30\n",
      "Name: PavedDrive, dtype: int64\n",
      "\n",
      "PoolQC 属性的不同取值和出现的次数：\n",
      "Gd    3\n",
      "Ex    2\n",
      "Fa    2\n",
      "Name: PoolQC, dtype: int64\n",
      "\n",
      "Fence 属性的不同取值和出现的次数：\n",
      "MnPrv    157\n",
      "GdPrv     59\n",
      "GdWo      54\n",
      "MnWw      11\n",
      "Name: Fence, dtype: int64\n",
      "\n",
      "MiscFeature 属性的不同取值和出现的次数：\n",
      "Shed    49\n",
      "Othr     2\n",
      "Gar2     2\n",
      "TenC     1\n",
      "Name: MiscFeature, dtype: int64\n",
      "\n",
      "SaleType 属性的不同取值和出现的次数：\n",
      "WD       1267\n",
      "New       122\n",
      "COD        43\n",
      "ConLD       9\n",
      "ConLI       5\n",
      "ConLw       5\n",
      "CWD         4\n",
      "Oth         3\n",
      "Con         2\n",
      "Name: SaleType, dtype: int64\n",
      "\n",
      "SaleCondition 属性的不同取值和出现的次数：\n",
      "Normal     1198\n",
      "Partial     125\n",
      "Abnorml     101\n",
      "Family       20\n",
      "Alloca       12\n",
      "AdjLand       4\n",
      "Name: SaleCondition, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# 对类别型特征，观察其取值范围及直方图\n",
    "categorical_features = train.select_dtypes(include=['object']).columns\n",
    "for col in categorical_features:\n",
    "    print('\\n%s 属性的不同取值和出现的次数：' %col)\n",
    "    print(train[col].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1a16cdad68>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 目标y（房屋价格）的直方图/分布\n",
    "fig = plt.figure()\n",
    "sns.distplot(train.SalePrice.values, bins=30, kde=True)\n",
    "plt.xlabel('SalePrice', fontsize=12)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "y分布类似高斯分布，但是右skew的，可以取对数log后更接近高斯分布。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.880940746034036"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 斜度\n",
    "skew(train.SalePrice.values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12121036730137275"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 取对数后斜度明显减小\n",
    "skew(np.log10(train.SalePrice.values))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10f770ef0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 取对数后更接近高斯分布\n",
    "fig = plt.figure()\n",
    "sns.distplot(np.log10(train.SalePrice.values), bins=30, kde=True)\n",
    "plt.xlabel('SalePrice', fontsize=12)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 特征工程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "# 去掉无关列‘Id’\n",
    "train.drop(['Id'], inplace=True, axis=1)\n",
    "test_id = test['Id']\n",
    "test.drop(['Id'], inplace=True, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 离群点检测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nhzoAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1a16c76a58>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 离群点（Outliers）检测\n",
    "plt.scatter(train['1stFlrSF'], train.SalePrice, c=\"blue\", marker=\"s\")\n",
    "plt.title('Look for outliers')\n",
    "plt.xlabel('1stFlrSF')\n",
    "plt.ylabel('SalePrice')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到有一个极端的离群点在图的右下角（面积很大，但价格很低）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 剔除离群点\n",
    "train = train[train['1stFlrSF'] < 4000]\n",
    "temp = train.reindex()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 1459 entries, 0 to 1459\n",
      "Data columns (total 80 columns):\n",
      "MSSubClass       1459 non-null int64\n",
      "MSZoning         1459 non-null object\n",
      "LotFrontage      1200 non-null float64\n",
      "LotArea          1459 non-null int64\n",
      "Street           1459 non-null object\n",
      "Alley            91 non-null object\n",
      "LotShape         1459 non-null object\n",
      "LandContour      1459 non-null object\n",
      "Utilities        1459 non-null object\n",
      "LotConfig        1459 non-null object\n",
      "LandSlope        1459 non-null object\n",
      "Neighborhood     1459 non-null object\n",
      "Condition1       1459 non-null object\n",
      "Condition2       1459 non-null object\n",
      "BldgType         1459 non-null object\n",
      "HouseStyle       1459 non-null object\n",
      "OverallQual      1459 non-null int64\n",
      "OverallCond      1459 non-null int64\n",
      "YearBuilt        1459 non-null int64\n",
      "YearRemodAdd     1459 non-null int64\n",
      "RoofStyle        1459 non-null object\n",
      "RoofMatl         1459 non-null object\n",
      "Exterior1st      1459 non-null object\n",
      "Exterior2nd      1459 non-null object\n",
      "MasVnrType       1451 non-null object\n",
      "MasVnrArea       1451 non-null float64\n",
      "ExterQual        1459 non-null object\n",
      "ExterCond        1459 non-null object\n",
      "Foundation       1459 non-null object\n",
      "BsmtQual         1422 non-null object\n",
      "BsmtCond         1422 non-null object\n",
      "BsmtExposure     1421 non-null object\n",
      "BsmtFinType1     1422 non-null object\n",
      "BsmtFinSF1       1459 non-null int64\n",
      "BsmtFinType2     1421 non-null object\n",
      "BsmtFinSF2       1459 non-null int64\n",
      "BsmtUnfSF        1459 non-null int64\n",
      "TotalBsmtSF      1459 non-null int64\n",
      "Heating          1459 non-null object\n",
      "HeatingQC        1459 non-null object\n",
      "CentralAir       1459 non-null object\n",
      "Electrical       1458 non-null object\n",
      "1stFlrSF         1459 non-null int64\n",
      "2ndFlrSF         1459 non-null int64\n",
      "LowQualFinSF     1459 non-null int64\n",
      "GrLivArea        1459 non-null int64\n",
      "BsmtFullBath     1459 non-null int64\n",
      "BsmtHalfBath     1459 non-null int64\n",
      "FullBath         1459 non-null int64\n",
      "HalfBath         1459 non-null int64\n",
      "BedroomAbvGr     1459 non-null int64\n",
      "KitchenAbvGr     1459 non-null int64\n",
      "KitchenQual      1459 non-null object\n",
      "TotRmsAbvGrd     1459 non-null int64\n",
      "Functional       1459 non-null object\n",
      "Fireplaces       1459 non-null int64\n",
      "FireplaceQu      769 non-null object\n",
      "GarageType       1378 non-null object\n",
      "GarageYrBlt      1378 non-null float64\n",
      "GarageFinish     1378 non-null object\n",
      "GarageCars       1459 non-null int64\n",
      "GarageArea       1459 non-null int64\n",
      "GarageQual       1378 non-null object\n",
      "GarageCond       1378 non-null object\n",
      "PavedDrive       1459 non-null object\n",
      "WoodDeckSF       1459 non-null int64\n",
      "OpenPorchSF      1459 non-null int64\n",
      "EnclosedPorch    1459 non-null int64\n",
      "3SsnPorch        1459 non-null int64\n",
      "ScreenPorch      1459 non-null int64\n",
      "PoolArea         1459 non-null int64\n",
      "PoolQC           6 non-null object\n",
      "Fence            281 non-null object\n",
      "MiscFeature      54 non-null object\n",
      "MiscVal          1459 non-null int64\n",
      "MoSold           1459 non-null int64\n",
      "YrSold           1459 non-null int64\n",
      "SaleType         1459 non-null object\n",
      "SaleCondition    1459 non-null object\n",
      "SalePrice        1459 non-null int64\n",
      "dtypes: float64(3), int64(34), object(43)\n",
      "memory usage: 923.3+ KB\n"
     ]
    }
   ],
   "source": [
    "train.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "剔除了1个样本点"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 缺失值处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 有些特征，用中值\\均值\\众数填充没有意义\n",
    "# 因为特征工程对训练集和测试集都需要进行，因此我们定义成函数，将数据集以参数形式传递\n",
    "def process_missvalue_by_meaning(df):\n",
    "    # LotFrontage: 房屋到街道直线距离，填充为0\n",
    "    df.loc[:, 'LotFrontage'] = df.loc[:, 'LotFrontage'].fillna(0)\n",
    "    \n",
    "    # Alley: 所在巷通道的类型, 填充为'None'\n",
    "    df.loc[:, 'Alley'] = df.loc[:, 'Alley'].fillna('None')\n",
    "    \n",
    "    # LotShape: 房地产形状，填充为‘Reg’普通\n",
    "    df.loc[:, 'LotShape'] = df.loc[:, 'LotShape'].fillna('Reg')\n",
    "    \n",
    "    # Utilities: 最有可能所有公共设施都可用，填充为'AllPub'\n",
    "    df.loc[:, 'Utilities'] = df.loc[:, 'Utilities'].fillna('AllPub')\n",
    "    \n",
    "    # Condition: 靠近主干道或铁路, 填充为'Norm'\n",
    "    df.loc[:, 'Condition1'] = df.loc[:, 'Condition1'].fillna('Norm')\n",
    "    df.loc[:, 'Condition2'] = df.loc[:, 'Condition2'].fillna('Norm')\n",
    "    \n",
    "    \n",
    "    # MasVnrType: NA意味着表层砌体类型没有砌体，类型设为0\n",
    "    df.loc[:, 'MasVnrType'] = df.loc[:, 'MasVnrType'].fillna('None')\n",
    "    df.loc[:, 'MasVnrArea'] = df.loc[:, 'MasVnrArea'].fillna(0)\n",
    "    \n",
    "    # ExterQual, ExterCond: 外部材料为平均水平, 填充为'TA'\n",
    "    df.loc[:, 'ExterQual'] = df.loc[:, 'ExterQual'].fillna('TA')\n",
    "    df.loc[:, 'ExterCond'] = df.loc[:, 'ExterCond'].fillna('TA')\n",
    "    \n",
    "    # BsmtQual, BsmtCond, BsmtExposure, BsmtFinType1, BsmtFinSF1, BsmtFinType2, BsmtFinSF2, BsmtFullBath, BsmtHalfBath: \n",
    "    # NA意味着没有地下室, 字符串类型填充‘NO’， 数值类型填充0\n",
    "    df.loc[:, 'BsmtQual'] = df.loc[:, 'BsmtQual'].fillna('No')\n",
    "    df.loc[:, 'BsmtCond'] = df.loc[:, 'BsmtCond'].fillna('No')\n",
    "    df.loc[:, 'BsmtExposure'] = df.loc[:, 'BsmtExposure'].fillna('No')\n",
    "    df.loc[:, 'BsmtFinType1'] = df.loc[:, 'BsmtFinType1'].fillna('No')\n",
    "    df.loc[:, 'BsmtFinSF1'] = df.loc[:, 'BsmtFinSF1'].fillna(0)\n",
    "    df.loc[:, 'BsmtFinType2'] = df.loc[:, 'BsmtFinType2'].fillna('No')\n",
    "    df.loc[:, 'BsmtFinSF2'] = df.loc[:, 'BsmtFinSF2'].fillna(0)\n",
    "    df.loc[:, 'BsmtUnfSF'] = df.loc[:, 'BsmtUnfSF'].fillna(0)\n",
    "    df.loc[:, 'BsmtFullBath'] = df.loc[:, 'BsmtFullBath'].fillna(0)\n",
    "    df.loc[:, 'BsmtHalfBath'] = df.loc[:, 'BsmtHalfBath'].fillna(0)\n",
    "    \n",
    "    # HeatingQC: 取暖质量和条件, 用典型'TA'填充\n",
    "    df.loc[:, 'HeatingQC'] = df.loc[:, 'HeatingQC'].fillna('TA')\n",
    "    \n",
    "    # CentralAir: NA意味着没有中央空调, 用'N'填充\n",
    "    df.loc[:, 'CentralAir'] = df.loc[:, 'CentralAir'].fillna('N')\n",
    "    \n",
    "    # HalfBath: NA意味着地上半浴室数目为0\n",
    "    df.loc[:, 'HalfBath'] = df.loc[:, 'HalfBath'].fillna(0)\n",
    "    \n",
    "    # BedroomAbvGr: NA意味着地下室之上的卧室数目为0\n",
    "    df.loc[:, 'BedroomAbvGr'] = df.loc[:, 'BedroomAbvGr'].fillna(0)\n",
    "    \n",
    "    # KitchenAbvGr: NA意味着地下室之上厨房数目为0\n",
    "    df.loc[:, 'KitchenAbvGr'] = df.loc[:, 'KitchenAbvGr'].fillna(0)\n",
    "\n",
    "    # KitchenQual: NA意味着厨房质量可能为典型'typical'\n",
    "    df.loc[:, 'KitchenQual'] = df.loc[:, 'KitchenQual'].fillna('TA')\n",
    "    \n",
    "    # TotRmsAbvGrd: NA意味着地下室之上房间总数可能为0\n",
    "    df.loc[:, 'TotRmsAbvGrd'] = df.loc[:, 'TotRmsAbvGrd'].fillna(0)\n",
    "    \n",
    "    # Functional: 家庭功能评级, 填充为典型值'Typ'\n",
    "    df.loc[:, 'Functional'] = df.loc[:, 'Functional'].fillna('Typ')\n",
    "    \n",
    "    # Fireplaces, FireplaceQu: 壁炉的数目, 壁炉质量, NA意味着没有壁炉, 填充0, 'NO'\n",
    "    df.loc[:, 'Fireplaces'] = df.loc[:, 'Fireplaces'].fillna(0)\n",
    "    df.loc[:, 'FireplaceQu'] = df.loc[:, 'FireplaceQu'].fillna('No')\n",
    "    \n",
    "    # GarageType, GarageFinish, GarageCars, GarageArea, GarageQual, GarageCond:\n",
    "    # NA意味着没有车库\n",
    "    df.loc[:, 'GarageType'] = df.loc[:, 'GarageType'].fillna('No')\n",
    "    df.loc[:, 'GarageFinish'] = df.loc[:, 'GarageFinish'].fillna('No')\n",
    "    df.loc[:, 'GarageCars'] = df.loc[:, 'GarageCars'].fillna(0)\n",
    "    df.loc[:, 'GarageArea'] = df.loc[:, 'GarageArea'].fillna(0)\n",
    "    df.loc[:, 'GarageQual'] = df.loc[:, 'GarageQual'].fillna('No')\n",
    "    df.loc[:, 'GarageCond'] = df.loc[:, 'GarageCond'].fillna('No')\n",
    "    \n",
    "    # PavedDrive: NA意味着没有铺设的车道\n",
    "    df.loc[:, 'PavedDrive'] = df.loc[:, 'PavedDrive'].fillna('N')\n",
    "    \n",
    "    # WoodDeckSF: NA意味着木头Deck面积为0\n",
    "    df.loc[:, 'WoodDeckSF'] = df.loc[:, 'WoodDeckSF'].fillna(0)\n",
    "    \n",
    "    # OpenPorchSF: NA意味着开放门廊面积为0\n",
    "    df.loc[:, 'OpenPorchSF'] = df.loc[:, 'OpenPorchSF'].fillna(0)\n",
    "    \n",
    "    # EnclosedPorch: NA意味着封闭门廊面积为0\n",
    "    df.loc[:, 'EnclosedPorch'] = df.loc[:, 'EnclosedPorch'].fillna(0)\n",
    "    \n",
    "    # ScreenPorch: NA意味着观景门廊面积为0\n",
    "    df.loc[:, 'ScreenPorch'] = df.loc[:, 'ScreenPorch'].fillna(0)\n",
    "    \n",
    "    # PoolArea, PoolQC: NA意味着没有游泳池, 填充为0, 'NO'\n",
    "    df.loc[:, 'PoolArea'] = df.loc[:, 'PoolArea'].fillna(0)\n",
    "    df.loc[:, 'PoolQC'] = df.loc[:, 'PoolQC'].fillna('No')\n",
    "    \n",
    "    # Fence: NA意味着没有围栏\n",
    "    df.loc[:, 'Fence'] = df.loc[:, 'Fence'].fillna('No')\n",
    "    \n",
    "    # MiscFeature, MiscVal: NA意味着没有杂项功能\n",
    "    df.loc[:, 'MiscFeature'] = df.loc[:, 'MiscFeature'].fillna('No')\n",
    "    df.loc[:, 'MiscVal'] = df.loc[:, 'MiscVal'].fillna(0)\n",
    "    \n",
    "    # SaleCondition: NA意味着销售条件正常'Normal'\n",
    "    df.loc[:, 'SaleCondition'] = df.loc[:, 'SaleCondition'].fillna('Normal')\n",
    "    \n",
    "    return df\n",
    "\n",
    "train = process_missvalue_by_meaning(train)\n",
    "test = process_missvalue_by_meaning(test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 有些特征用数值表示类别，需要转换成类别\n",
    "# MSSubClass: 房地产建筑类别\n",
    "# \n",
    "def numerical2cat(df):\n",
    "    df.replace({'MSSubClass':{20:'SC20', 30:'SC30', 40:'SC40', 45:'SC45', \n",
    "                              50:'SC50', 60:'SC60', 70:'SC70', 75:'SC75', \n",
    "                              80:'SC80', 85:'SC85', 90:'SC90', 120:'SC120', \n",
    "                              150:'SC150', 160:'SC160', 180:'SC180', 190:'SC190'},\n",
    "                'MoSold':{1:'Jan', 2:'Feb', 3:'Mar', 4:'Apr', 5:'May', 6:'Jun', \n",
    "                          7:'Jul', 8:'Aug', 9:'Sep', 10:'Oct', 11:'Nov', 12:'Dec'}\n",
    "               }, inplace=True)\n",
    "    return df\n",
    "\n",
    "train = numerical2cat(train)\n",
    "test = numerical2cat(test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 有些类别型特征，可以编码成一列有序数字，把信息隐藏在序列里\n",
    "def cat2numerical(df):\n",
    "    df.replace({'Street':{'Grvl':1, 'Pave':2},\n",
    "                'Alley':{'None':0, 'Grvl':1, 'Pave':2},\n",
    "                'LotShape':{'IR3':1, 'IR2':2, 'IR1':3, 'Reg':4},\n",
    "                'Utilities':{'ELO':1, 'NoSeWa':2, 'NoSewr':3, 'AllPub':4},\n",
    "                'LandSlope':{'Sev':1, 'Mod':2, 'Gtl':3},\n",
    "                'ExterQual':{'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'ExterCond':{'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'BsmtQual':{'No':0, 'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'BsmtCond':{'No':0, 'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'BsmtExposure':{'No':0, 'Mn':1, 'Av':2, 'Gd':3},\n",
    "                'BsmtFinType1':{'No':0, 'Unf':1, 'LwQ':2, 'Rec':3, 'BLQ':4, 'ALQ':5, 'GLQ':6},\n",
    "                'BsmtFinType2':{'No':0, 'Unf':1, 'LwQ':2, 'Rec':3, 'BLQ':4, 'ALQ':5, 'GLQ':6},\n",
    "                'HeatingQC':{'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'KitchenQual':{'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'Functional':{'Sal':1, 'Sev':2, 'Maj2':3, 'Maj1':4, 'Mod':5, 'Min2':6, 'Min1':7, 'Typ':8},\n",
    "                'FireplaceQu':{'No':0, 'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'GarageQual':{'No':0, 'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'GarageCond':{'No':0, 'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5},\n",
    "                'PavedDrive':{'N':0, 'P':1, 'Y':2},\n",
    "                'PoolQC':{'No':0, 'Po':1, 'Fa':2, 'TA':3, 'Gd':4}\n",
    "    }, inplace=True)\n",
    "    \n",
    "    return df\n",
    "\n",
    "train = cat2numerical(train)\n",
    "test = cat2numerical(test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 通过以下方式创造一些新特征\n",
    " 1. 简化已有特征\n",
    " 2. 联合已有特征\n",
    " 3. 现有重要特征（top 10）的多项式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 简化已有特征: 合并类别\n",
    "def simplify(df):\n",
    "    df['SimplOverallQual'] = df.OverallQual.replace({1:1, 2:1, 3:1, # bad\n",
    "                                                     4:2, 5:2, 6:2, # average\n",
    "                                                     7:3, 8:3, 9:3, 10:3 # good\n",
    "                                                    }, inplace = True)\n",
    "    df['SimplOverallCond'] = df.OverallCond.replace({1:1, 2:1, 3:1, # bad\n",
    "                                                     4:2, 5:2, 6:2, # average\n",
    "                                                     7:3, 8:3, 9:3, 10:3 # good\n",
    "                                                    },inplace = True)\n",
    "    df['SimplPoolQC'] = df.PoolQC.replace({1:1, 2:1, # average\n",
    "                                           3:2, 4:2 # good\n",
    "                                          },inplace = True)\n",
    "    df['SimplGarageCond'] = df.GarageCond.replace({1:1, # bad\n",
    "                                                   2:1, 3:1, # average\n",
    "                                                   4:2, 5:2 # good\n",
    "                                                  },inplace = True)\n",
    "    df['SimplGarageQual'] = df.GarageQual.replace({1:1, # bad\n",
    "                                                   2:1, 3:1, # average\n",
    "                                                   4:2, 5:2 # good\n",
    "                                                  },inplace = True)\n",
    "    df['SimplFireplaceQu'] = df.FireplaceQu.replace({1:1, # bad\n",
    "                                                     2:1, 3:1, # average\n",
    "                                                     4:2, 5:2 # good\n",
    "                                                    },inplace = True)\n",
    "    df['SimplFireplaceQu'] = df.FireplaceQu.replace({1:1, # bad\n",
    "                                                     2:1, 3:1, # average\n",
    "                                                     4:2, 5:2 # good\n",
    "                                                    },inplace = True)\n",
    "    df['SimplFunctional'] = df.Functional.replace({1:1, 2:1, # bad\n",
    "                                                   3:2, 4:2, # major\n",
    "                                                   5:3, 6:3, 7:3, # minor\n",
    "                                                   8:4 # typical\n",
    "                                                  },inplace = True)\n",
    "    df['SimplKitchenQual'] = df.KitchenQual.replace({1:1, # bad\n",
    "                                                     2:1, 3:1, # average\n",
    "                                                     4:2, 5:2 # good\n",
    "                                                    },inplace = True)\n",
    "    df['SimplHeatingQC'] = df.HeatingQC.replace({1:1, # bad\n",
    "                                                 2:1, 3:1, # average\n",
    "                                                 4:2, 5:2 # good\n",
    "                                                },inplace = True)\n",
    "    df['SimplBsmtFinType1'] = df.BsmtFinType1.replace({1:1, # unfinished\n",
    "                                                       2:1, 3:1, # rec room\n",
    "                                                       4:2, 5:2, 6:2 # living quarters\n",
    "                                                      },inplace = True)\n",
    "    df['SimplBsmtFinType2'] = df.BsmtFinType2.replace({1:1, # unfinished\n",
    "                                                       2:1, 3:1, # rec room\n",
    "                                                       4:2, 5:2, 6:2 # living quarters\n",
    "                                                      },inplace = True)\n",
    "    df['SimplBsmtCond'] = df.BsmtCond.replace({1:1, # bad\n",
    "                                               2:1, 3:1, # average\n",
    "                                               4:2, 5:2 # good\n",
    "                                              },inplace = True)\n",
    "    df['SimplBsmtQual'] = df.BsmtQual.replace({1:1, # bad\n",
    "                                               2:1, 3:1, # average\n",
    "                                               4:2, 5:2 # good\n",
    "                                              },inplace = True)\n",
    "    df['SimplExterCond'] = df.ExterCond.replace({1:1, # bad\n",
    "                                                 2:1, 3:1, # average\n",
    "                                                 4:2, 5:2 # good\n",
    "                                                },inplace = True)\n",
    "    df['SimplExterQual'] = df.ExterQual.replace({1:1, # bad\n",
    "                                                 2:1, 3:1, # average\n",
    "                                                 4:2, 5:2 # good\n",
    "                                                },inplace = True)\n",
    "    \n",
    "    return df\n",
    "\n",
    "train = simplify(train)\n",
    "test = simplify(test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 合并已有特征\n",
    "def Combine(df):\n",
    "    # 房子总体质量等级 = 整体材质和完成品质 × 总体条件评级\n",
    "    df['OverallGrade'] = df['OverallQual'] * df['OverallCond']\n",
    "    # 车库总体质量等级 = 车库质量 × 车库条件\n",
    "    df['GarageGrade'] = df['GarageQual'] * df['GarageCond']\n",
    "    # 外墙总体质量等级 = 材料质量 × 现状\n",
    "    df['ExterGrade'] = df['ExterQual'] * df['ExterCond']\n",
    "    # 厨房得分 = 地上厨房数量 × 厨房质量\n",
    "    df['KitchenScore'] = df['KitchenAbvGr'] * df['KitchenQual']\n",
    "    # 壁炉总体得分 = 壁炉数量 × 壁炉质量\n",
    "    df['FireplaceScore'] = df['Fireplaces'] * df['FireplaceQu']\n",
    "    # 车库总体得分 = 车库面积 × 车库质量\n",
    "    df['GarageScore'] = df['GarageArea'] * df['GarageQual']\n",
    "    # 游泳池总体得分 = 游泳池面积 × 游泳池质量\n",
    "    df['PoolScore'] = df['PoolArea'] * df['PoolQC']\n",
    "    # 简化的房子总体质量等级 = 简化的总体质量 × 简化的总体现状\n",
    "    df['SimplOverallGrade'] = df['SimplOverallQual'] * df['SimplOverallCond']\n",
    "    # 简化的外墙总体质量 = 简化的外墙质量 × 简化的外墙现状\n",
    "    df['SimplExterGrade'] = df['SimplExterQual'] * df['SimplExterCond']\n",
    "    # 简化的游泳池总体得分 = 游泳池面积 × 简化的游泳池质量\n",
    "    df['SimplPoolScore'] = df['PoolArea'] * df['SimplPoolQC']\n",
    "    # 简化的车库总体得分 = 车库面积 × 简化的车库质量\n",
    "    df['SimplGarageScore'] = df['GarageArea'] * df['SimplGarageQual']\n",
    "    # 简化的壁炉总体得分 = 壁炉数量 × 简化的壁炉质量\n",
    "    df['SimplFireplaceScore'] = df['Fireplaces'] * df['SimplFireplaceQu']\n",
    "    # 简化的厨房总体得分 = 地上厨房数量 × 简化的厨房质量\n",
    "    df['SimplKitchenScore'] = df['KitchenAbvGr'] * df['SimplKitchenQual']\n",
    "    # 浴室总数 = 地下全浴室数目 + 0.5×地下半浴室数目 + 地上全浴室数目 + 0.5×地上半浴室数目\n",
    "    df['TotalBath'] = df['BsmtFullBath'] + (0.5 * df['BsmtHalfBath']) + \\\n",
    "    df['FullBath'] + (0.5 * df['HalfBath'])\n",
    "    # 房子总面积 (包括地下室) = 地上居住面积 + 地下室总面积\n",
    "    df['AllSF'] = df['GrLivArea'] + df['TotalBsmtSF']\n",
    "    # 一层加二层总面积\n",
    "    df['AllFlrsSF'] = df['1stFlrSF'] + df['2ndFlrSF']\n",
    "    # 门廊总面积 = 开放门廊面积 + 封闭门廊面积 + 三季门廊面积 + 观景门廊面积\n",
    "    df['AllPorchSF'] = df['OpenPorchSF'] + df['EnclosedPorch'] + \\\n",
    "    df['3SsnPorch'] + df['ScreenPorch']\n",
    "    # 是否有表层砌体, 1:有, 0:没有\n",
    "    df['HasMasVnr'] = df.MasVnrType.replace({'BrkCmn':1, 'BrkFace':1, 'CBlock':1, 'Stone':1,'None':0})\n",
    "    # 售前房子是否完工\n",
    "    df['BoughtOffPlan'] = df.SaleCondition.replace({'Abnorml':0, 'Alloca':0, 'AdjLand':0, 'Family':0, \n",
    "                                                    'Normal':0, 'Partial':1})\n",
    "    \n",
    "    return df\n",
    "\n",
    "train = Combine(train)\n",
    "test = Combine(test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SalePrice         1.000\n",
      "AllSF             0.817\n",
      "AllFlrsSF         0.734\n",
      "GrLivArea         0.726\n",
      "OverallQual       0.663\n",
      "TotalBsmtSF       0.646\n",
      "GarageCars        0.641\n",
      "TotalBath         0.634\n",
      "GarageArea        0.628\n",
      "1stFlrSF          0.626\n",
      "ExterQual         0.616\n",
      "GarageScore       0.607\n",
      "KitchenQual       0.571\n",
      "FullBath          0.561\n",
      "TotRmsAbvGrd      0.536\n",
      "BsmtQual          0.534\n",
      "YearBuilt         0.523\n",
      "YearRemodAdd      0.508\n",
      "KitchenScore      0.492\n",
      "GarageYrBlt       0.487\n",
      "MasVnrArea        0.476\n",
      "FireplaceQu       0.472\n",
      "OverallGrade      0.471\n",
      "FireplaceScore    0.470\n",
      "Fireplaces        0.470\n",
      "ExterGrade        0.469\n",
      "BsmtFinSF1        0.407\n",
      "HasMasVnr         0.368\n",
      "BsmtExposure      0.363\n",
      "HeatingQC         0.357\n",
      "                  ...  \n",
      "BsmtFinType1      0.262\n",
      "GarageQual        0.235\n",
      "PavedDrive        0.231\n",
      "BsmtFullBath      0.228\n",
      "GarageCond        0.216\n",
      "LotFrontage       0.215\n",
      "BsmtUnfSF         0.214\n",
      "AllPorchSF        0.196\n",
      "GarageGrade       0.187\n",
      "BedroomAbvGr      0.168\n",
      "BsmtCond          0.161\n",
      "Functional        0.116\n",
      "ScreenPorch       0.111\n",
      "PoolArea          0.099\n",
      "BsmtFinType2      0.073\n",
      "3SsnPorch         0.045\n",
      "Street            0.041\n",
      "Utilities         0.014\n",
      "BsmtFinSF2       -0.011\n",
      "BsmtHalfBath     -0.017\n",
      "MiscVal          -0.021\n",
      "LowQualFinSF     -0.026\n",
      "YrSold           -0.029\n",
      "ExterCond        -0.048\n",
      "LandSlope        -0.051\n",
      "OverallCond      -0.067\n",
      "Alley            -0.093\n",
      "EnclosedPorch    -0.129\n",
      "KitchenAbvGr     -0.136\n",
      "LotShape         -0.270\n",
      "Name: SalePrice, Length: 66, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# 找到与目标相关的最重要特征\n",
    "corr = train.corr()\n",
    "corr.sort_values(['SalePrice'], ascending=False, inplace=True)\n",
    "print(corr.SalePrice)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Find the most important features relative to target\n",
      "0.60726790195\n"
     ]
    }
   ],
   "source": [
    "threshold = corr.SalePrice.iloc[11]\n",
    "print('Find the most important features relative to target')\n",
    "print(threshold)\n",
    "top10_cols = (corr.SalePrice[corr['SalePrice']>threshold]).axes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 创建新特征\n",
    "# 做前10个特征的3个多项式\n",
    "def Polynomials_top10(df, top10_cols):\n",
    "    for i in range(1, 11):\n",
    "        new_cols_2 = top10_cols[0][i] + '_s' + str(2)\n",
    "        new_cols_3 = top10_cols[0][i] + '_s' + str(3)\n",
    "        new_cols_sq = top10_cols[0][i] + '_sq'\n",
    "        \n",
    "        df[new_cols_2] = df[top10_cols[0][i]] ** 2\n",
    "        df[new_cols_3] = df[top10_cols[0][i]] ** 3\n",
    "        df[new_cols_sq] = np.sqrt(df[top10_cols[0][i]])\n",
    "        \n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "train = Polynomials_top10(train, top10_cols)\n",
    "test = Polynomials_top10(test, top10_cols)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Numerical features: 95\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 1459 entries, 0 to 1459\n",
      "Columns: 144 entries, MSSubClass to ExterQual_sq\n",
      "dtypes: float64(16), int64(80), object(48)\n",
      "memory usage: 1.6+ MB\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 1459 entries, 0 to 1459\n",
      "Data columns (total 95 columns):\n",
      "LotFrontage       1459 non-null float64\n",
      "LotArea           1459 non-null int64\n",
      "Street            1459 non-null int64\n",
      "Alley             1459 non-null int64\n",
      "LotShape          1459 non-null int64\n",
      "Utilities         1459 non-null int64\n",
      "LandSlope         1459 non-null int64\n",
      "OverallQual       1459 non-null int64\n",
      "OverallCond       1459 non-null int64\n",
      "YearBuilt         1459 non-null int64\n",
      "YearRemodAdd      1459 non-null int64\n",
      "MasVnrArea        1459 non-null float64\n",
      "ExterQual         1459 non-null int64\n",
      "ExterCond         1459 non-null int64\n",
      "BsmtQual          1459 non-null int64\n",
      "BsmtCond          1459 non-null int64\n",
      "BsmtExposure      1459 non-null int64\n",
      "BsmtFinType1      1459 non-null int64\n",
      "BsmtFinSF1        1459 non-null int64\n",
      "BsmtFinType2      1459 non-null int64\n",
      "BsmtFinSF2        1459 non-null int64\n",
      "BsmtUnfSF         1459 non-null int64\n",
      "TotalBsmtSF       1459 non-null int64\n",
      "HeatingQC         1459 non-null int64\n",
      "1stFlrSF          1459 non-null int64\n",
      "2ndFlrSF          1459 non-null int64\n",
      "LowQualFinSF      1459 non-null int64\n",
      "GrLivArea         1459 non-null int64\n",
      "BsmtFullBath      1459 non-null int64\n",
      "BsmtHalfBath      1459 non-null int64\n",
      "FullBath          1459 non-null int64\n",
      "HalfBath          1459 non-null int64\n",
      "BedroomAbvGr      1459 non-null int64\n",
      "KitchenAbvGr      1459 non-null int64\n",
      "KitchenQual       1459 non-null int64\n",
      "TotRmsAbvGrd      1459 non-null int64\n",
      "Functional        1459 non-null int64\n",
      "Fireplaces        1459 non-null int64\n",
      "FireplaceQu       1459 non-null int64\n",
      "GarageYrBlt       1378 non-null float64\n",
      "GarageCars        1459 non-null int64\n",
      "GarageArea        1459 non-null int64\n",
      "GarageQual        1459 non-null int64\n",
      "GarageCond        1459 non-null int64\n",
      "PavedDrive        1459 non-null int64\n",
      "WoodDeckSF        1459 non-null int64\n",
      "OpenPorchSF       1459 non-null int64\n",
      "EnclosedPorch     1459 non-null int64\n",
      "3SsnPorch         1459 non-null int64\n",
      "ScreenPorch       1459 non-null int64\n",
      "PoolArea          1459 non-null int64\n",
      "MiscVal           1459 non-null int64\n",
      "YrSold            1459 non-null int64\n",
      "OverallGrade      1459 non-null int64\n",
      "GarageGrade       1459 non-null int64\n",
      "ExterGrade        1459 non-null int64\n",
      "KitchenScore      1459 non-null int64\n",
      "FireplaceScore    1459 non-null int64\n",
      "GarageScore       1459 non-null int64\n",
      "TotalBath         1459 non-null float64\n",
      "AllSF             1459 non-null int64\n",
      "AllFlrsSF         1459 non-null int64\n",
      "AllPorchSF        1459 non-null int64\n",
      "HasMasVnr         1459 non-null int64\n",
      "BoughtOffPlan     1459 non-null int64\n",
      "AllSF_s2          1459 non-null int64\n",
      "AllSF_s3          1459 non-null int64\n",
      "AllSF_sq          1459 non-null float64\n",
      "AllFlrsSF_s2      1459 non-null int64\n",
      "AllFlrsSF_s3      1459 non-null int64\n",
      "AllFlrsSF_sq      1459 non-null float64\n",
      "GrLivArea_s2      1459 non-null int64\n",
      "GrLivArea_s3      1459 non-null int64\n",
      "GrLivArea_sq      1459 non-null float64\n",
      "OverallQual_s2    1459 non-null int64\n",
      "OverallQual_s3    1459 non-null int64\n",
      "OverallQual_sq    1459 non-null float64\n",
      "TotalBsmtSF_s2    1459 non-null int64\n",
      "TotalBsmtSF_s3    1459 non-null int64\n",
      "TotalBsmtSF_sq    1459 non-null float64\n",
      "GarageCars_s2     1459 non-null int64\n",
      "GarageCars_s3     1459 non-null int64\n",
      "GarageCars_sq     1459 non-null float64\n",
      "TotalBath_s2      1459 non-null float64\n",
      "TotalBath_s3      1459 non-null float64\n",
      "TotalBath_sq      1459 non-null float64\n",
      "GarageArea_s2     1459 non-null int64\n",
      "GarageArea_s3     1459 non-null int64\n",
      "GarageArea_sq     1459 non-null float64\n",
      "1stFlrSF_s2       1459 non-null int64\n",
      "1stFlrSF_s3       1459 non-null int64\n",
      "1stFlrSF_sq       1459 non-null float64\n",
      "ExterQual_s2      1459 non-null int64\n",
      "ExterQual_s3      1459 non-null int64\n",
      "ExterQual_sq      1459 non-null float64\n",
      "dtypes: float64(16), int64(79)\n",
      "memory usage: 1.1 MB\n",
      "NAs for numerical features in df: LotFrontage       0\n",
      "LotArea           0\n",
      "Street            0\n",
      "Alley             0\n",
      "LotShape          0\n",
      "Utilities         0\n",
      "LandSlope         0\n",
      "OverallQual       0\n",
      "OverallCond       0\n",
      "YearBuilt         0\n",
      "YearRemodAdd      0\n",
      "MasVnrArea        0\n",
      "ExterQual         0\n",
      "ExterCond         0\n",
      "BsmtQual          0\n",
      "BsmtCond          0\n",
      "BsmtExposure      0\n",
      "BsmtFinType1      0\n",
      "BsmtFinSF1        0\n",
      "BsmtFinType2      0\n",
      "BsmtFinSF2        0\n",
      "BsmtUnfSF         0\n",
      "TotalBsmtSF       0\n",
      "HeatingQC         0\n",
      "1stFlrSF          0\n",
      "2ndFlrSF          0\n",
      "LowQualFinSF      0\n",
      "GrLivArea         0\n",
      "BsmtFullBath      0\n",
      "BsmtHalfBath      0\n",
      "                 ..\n",
      "AllSF_s2          0\n",
      "AllSF_s3          0\n",
      "AllSF_sq          0\n",
      "AllFlrsSF_s2      0\n",
      "AllFlrsSF_s3      0\n",
      "AllFlrsSF_sq      0\n",
      "GrLivArea_s2      0\n",
      "GrLivArea_s3      0\n",
      "GrLivArea_sq      0\n",
      "OverallQual_s2    0\n",
      "OverallQual_s3    0\n",
      "OverallQual_sq    0\n",
      "TotalBsmtSF_s2    0\n",
      "TotalBsmtSF_s3    0\n",
      "TotalBsmtSF_sq    0\n",
      "GarageCars_s2     0\n",
      "GarageCars_s3     0\n",
      "GarageCars_sq     0\n",
      "TotalBath_s2      0\n",
      "TotalBath_s3      0\n",
      "TotalBath_sq      0\n",
      "GarageArea_s2     0\n",
      "GarageArea_s3     0\n",
      "GarageArea_sq     0\n",
      "1stFlrSF_s2       0\n",
      "1stFlrSF_s3       0\n",
      "1stFlrSF_sq       0\n",
      "ExterQual_s2      0\n",
      "ExterQual_s3      0\n",
      "ExterQual_sq      0\n",
      "Length: 95, dtype: int64\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 1459 entries, 0 to 1459\n",
      "Data columns (total 95 columns):\n",
      "LotFrontage       1459 non-null float64\n",
      "LotArea           1459 non-null int64\n",
      "Street            1459 non-null int64\n",
      "Alley             1459 non-null int64\n",
      "LotShape          1459 non-null int64\n",
      "Utilities         1459 non-null int64\n",
      "LandSlope         1459 non-null int64\n",
      "OverallQual       1459 non-null int64\n",
      "OverallCond       1459 non-null int64\n",
      "YearBuilt         1459 non-null int64\n",
      "YearRemodAdd      1459 non-null int64\n",
      "MasVnrArea        1459 non-null float64\n",
      "ExterQual         1459 non-null int64\n",
      "ExterCond         1459 non-null int64\n",
      "BsmtQual          1459 non-null int64\n",
      "BsmtCond          1459 non-null int64\n",
      "BsmtExposure      1459 non-null int64\n",
      "BsmtFinType1      1459 non-null int64\n",
      "BsmtFinSF1        1459 non-null int64\n",
      "BsmtFinType2      1459 non-null int64\n",
      "BsmtFinSF2        1459 non-null int64\n",
      "BsmtUnfSF         1459 non-null int64\n",
      "TotalBsmtSF       1459 non-null int64\n",
      "HeatingQC         1459 non-null int64\n",
      "1stFlrSF          1459 non-null int64\n",
      "2ndFlrSF          1459 non-null int64\n",
      "LowQualFinSF      1459 non-null int64\n",
      "GrLivArea         1459 non-null int64\n",
      "BsmtFullBath      1459 non-null int64\n",
      "BsmtHalfBath      1459 non-null int64\n",
      "FullBath          1459 non-null int64\n",
      "HalfBath          1459 non-null int64\n",
      "BedroomAbvGr      1459 non-null int64\n",
      "KitchenAbvGr      1459 non-null int64\n",
      "KitchenQual       1459 non-null int64\n",
      "TotRmsAbvGrd      1459 non-null int64\n",
      "Functional        1459 non-null int64\n",
      "Fireplaces        1459 non-null int64\n",
      "FireplaceQu       1459 non-null int64\n",
      "GarageYrBlt       1459 non-null float64\n",
      "GarageCars        1459 non-null int64\n",
      "GarageArea        1459 non-null int64\n",
      "GarageQual        1459 non-null int64\n",
      "GarageCond        1459 non-null int64\n",
      "PavedDrive        1459 non-null int64\n",
      "WoodDeckSF        1459 non-null int64\n",
      "OpenPorchSF       1459 non-null int64\n",
      "EnclosedPorch     1459 non-null int64\n",
      "3SsnPorch         1459 non-null int64\n",
      "ScreenPorch       1459 non-null int64\n",
      "PoolArea          1459 non-null int64\n",
      "MiscVal           1459 non-null int64\n",
      "YrSold            1459 non-null int64\n",
      "OverallGrade      1459 non-null int64\n",
      "GarageGrade       1459 non-null int64\n",
      "ExterGrade        1459 non-null int64\n",
      "KitchenScore      1459 non-null int64\n",
      "FireplaceScore    1459 non-null int64\n",
      "GarageScore       1459 non-null int64\n",
      "TotalBath         1459 non-null float64\n",
      "AllSF             1459 non-null int64\n",
      "AllFlrsSF         1459 non-null int64\n",
      "AllPorchSF        1459 non-null int64\n",
      "HasMasVnr         1459 non-null int64\n",
      "BoughtOffPlan     1459 non-null int64\n",
      "AllSF_s2          1459 non-null int64\n",
      "AllSF_s3          1459 non-null int64\n",
      "AllSF_sq          1459 non-null float64\n",
      "AllFlrsSF_s2      1459 non-null int64\n",
      "AllFlrsSF_s3      1459 non-null int64\n",
      "AllFlrsSF_sq      1459 non-null float64\n",
      "GrLivArea_s2      1459 non-null int64\n",
      "GrLivArea_s3      1459 non-null int64\n",
      "GrLivArea_sq      1459 non-null float64\n",
      "OverallQual_s2    1459 non-null int64\n",
      "OverallQual_s3    1459 non-null int64\n",
      "OverallQual_sq    1459 non-null float64\n",
      "TotalBsmtSF_s2    1459 non-null int64\n",
      "TotalBsmtSF_s3    1459 non-null int64\n",
      "TotalBsmtSF_sq    1459 non-null float64\n",
      "GarageCars_s2     1459 non-null int64\n",
      "GarageCars_s3     1459 non-null int64\n",
      "GarageCars_sq     1459 non-null float64\n",
      "TotalBath_s2      1459 non-null float64\n",
      "TotalBath_s3      1459 non-null float64\n",
      "TotalBath_sq      1459 non-null float64\n",
      "GarageArea_s2     1459 non-null int64\n",
      "GarageArea_s3     1459 non-null int64\n",
      "GarageArea_sq     1459 non-null float64\n",
      "1stFlrSF_s2       1459 non-null int64\n",
      "1stFlrSF_s3       1459 non-null int64\n",
      "1stFlrSF_sq       1459 non-null float64\n",
      "ExterQual_s2      1459 non-null int64\n",
      "ExterQual_s3      1459 non-null int64\n",
      "ExterQual_sq      1459 non-null float64\n",
      "dtypes: float64(16), int64(79)\n",
      "memory usage: 1.1 MB\n"
     ]
    }
   ],
   "source": [
    "# 对训练集的其他数值型特征进行空缺值填补(中值填补)\n",
    "# 返回填补后的dataframe, 以及每列的中值, 用于填补测试集的空缺值\n",
    "# 数值型特征还要进行数值标准化\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "def fillna_numerical_train(df):\n",
    "    numerical_features = df.select_dtypes(exclude=['object']).columns\n",
    "    \n",
    "    numerical_features = numerical_features.drop('SalePrice')\n",
    "    print('Numerical features: ' + str(len(numerical_features)))\n",
    "    \n",
    "    df.info()\n",
    "    df_num = df[numerical_features]\n",
    "    df_num.info()\n",
    "    \n",
    "    medians = df_num.median()\n",
    "    \n",
    "    # 用中值替换数值型特征中的缺失值\n",
    "    print('NAs for numerical features in df: ' + str(df_num.isnull().sum()))\n",
    "    df_num = df_num.fillna(medians)\n",
    "    \n",
    "    df_num.info()\n",
    "    # 分别初始化对特征和目标值的标准化器\n",
    "    ss_X = StandardScaler()\n",
    "    \n",
    "    # 对训练特征进行标准化处理\n",
    "    temp = ss_X.fit_transform(df_num)\n",
    "    df_num = pd.DataFrame(data=temp, columns=numerical_features, index=df_num.index)\n",
    "    \n",
    "    return df_num, medians, ss_X\n",
    "train_num, medians, ss_X = fillna_numerical_train(train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 1459 entries, 0 to 1459\n",
      "Data columns (total 95 columns):\n",
      "LotFrontage       1459 non-null float64\n",
      "LotArea           1459 non-null float64\n",
      "Street            1459 non-null float64\n",
      "Alley             1459 non-null float64\n",
      "LotShape          1459 non-null float64\n",
      "Utilities         1459 non-null float64\n",
      "LandSlope         1459 non-null float64\n",
      "OverallQual       1459 non-null float64\n",
      "OverallCond       1459 non-null float64\n",
      "YearBuilt         1459 non-null float64\n",
      "YearRemodAdd      1459 non-null float64\n",
      "MasVnrArea        1459 non-null float64\n",
      "ExterQual         1459 non-null float64\n",
      "ExterCond         1459 non-null float64\n",
      "BsmtQual          1459 non-null float64\n",
      "BsmtCond          1459 non-null float64\n",
      "BsmtExposure      1459 non-null float64\n",
      "BsmtFinType1      1459 non-null float64\n",
      "BsmtFinSF1        1459 non-null float64\n",
      "BsmtFinType2      1459 non-null float64\n",
      "BsmtFinSF2        1459 non-null float64\n",
      "BsmtUnfSF         1459 non-null float64\n",
      "TotalBsmtSF       1459 non-null float64\n",
      "HeatingQC         1459 non-null float64\n",
      "1stFlrSF          1459 non-null float64\n",
      "2ndFlrSF          1459 non-null float64\n",
      "LowQualFinSF      1459 non-null float64\n",
      "GrLivArea         1459 non-null float64\n",
      "BsmtFullBath      1459 non-null float64\n",
      "BsmtHalfBath      1459 non-null float64\n",
      "FullBath          1459 non-null float64\n",
      "HalfBath          1459 non-null float64\n",
      "BedroomAbvGr      1459 non-null float64\n",
      "KitchenAbvGr      1459 non-null float64\n",
      "KitchenQual       1459 non-null float64\n",
      "TotRmsAbvGrd      1459 non-null float64\n",
      "Functional        1459 non-null float64\n",
      "Fireplaces        1459 non-null float64\n",
      "FireplaceQu       1459 non-null float64\n",
      "GarageYrBlt       1459 non-null float64\n",
      "GarageCars        1459 non-null float64\n",
      "GarageArea        1459 non-null float64\n",
      "GarageQual        1459 non-null float64\n",
      "GarageCond        1459 non-null float64\n",
      "PavedDrive        1459 non-null float64\n",
      "WoodDeckSF        1459 non-null float64\n",
      "OpenPorchSF       1459 non-null float64\n",
      "EnclosedPorch     1459 non-null float64\n",
      "3SsnPorch         1459 non-null float64\n",
      "ScreenPorch       1459 non-null float64\n",
      "PoolArea          1459 non-null float64\n",
      "MiscVal           1459 non-null float64\n",
      "YrSold            1459 non-null float64\n",
      "OverallGrade      1459 non-null float64\n",
      "GarageGrade       1459 non-null float64\n",
      "ExterGrade        1459 non-null float64\n",
      "KitchenScore      1459 non-null float64\n",
      "FireplaceScore    1459 non-null float64\n",
      "GarageScore       1459 non-null float64\n",
      "TotalBath         1459 non-null float64\n",
      "AllSF             1459 non-null float64\n",
      "AllFlrsSF         1459 non-null float64\n",
      "AllPorchSF        1459 non-null float64\n",
      "HasMasVnr         1459 non-null float64\n",
      "BoughtOffPlan     1459 non-null float64\n",
      "AllSF_s2          1459 non-null float64\n",
      "AllSF_s3          1459 non-null float64\n",
      "AllSF_sq          1459 non-null float64\n",
      "AllFlrsSF_s2      1459 non-null float64\n",
      "AllFlrsSF_s3      1459 non-null float64\n",
      "AllFlrsSF_sq      1459 non-null float64\n",
      "GrLivArea_s2      1459 non-null float64\n",
      "GrLivArea_s3      1459 non-null float64\n",
      "GrLivArea_sq      1459 non-null float64\n",
      "OverallQual_s2    1459 non-null float64\n",
      "OverallQual_s3    1459 non-null float64\n",
      "OverallQual_sq    1459 non-null float64\n",
      "TotalBsmtSF_s2    1459 non-null float64\n",
      "TotalBsmtSF_s3    1459 non-null float64\n",
      "TotalBsmtSF_sq    1459 non-null float64\n",
      "GarageCars_s2     1459 non-null float64\n",
      "GarageCars_s3     1459 non-null float64\n",
      "GarageCars_sq     1459 non-null float64\n",
      "TotalBath_s2      1459 non-null float64\n",
      "TotalBath_s3      1459 non-null float64\n",
      "TotalBath_sq      1459 non-null float64\n",
      "GarageArea_s2     1459 non-null float64\n",
      "GarageArea_s3     1459 non-null float64\n",
      "GarageArea_sq     1459 non-null float64\n",
      "1stFlrSF_s2       1459 non-null float64\n",
      "1stFlrSF_s3       1459 non-null float64\n",
      "1stFlrSF_sq       1459 non-null float64\n",
      "ExterQual_s2      1459 non-null float64\n",
      "ExterQual_s3      1459 non-null float64\n",
      "ExterQual_sq      1459 non-null float64\n",
      "dtypes: float64(95)\n",
      "memory usage: 1.1 MB\n"
     ]
    }
   ],
   "source": [
    "train_num.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Numerical features: 95\n",
      "NAs for numerical features in df: 86\n",
      "Remaining NAs for numerical features in df: 0\n"
     ]
    }
   ],
   "source": [
    "# 对测试集的其他数值型特征进行空缺值填补(用训练集中对应列的中值填补)\n",
    "def fillna_numerical_test(df, medians, ss_X):\n",
    "    numerical_features = df.select_dtypes(exclude=['object']).columns\n",
    "    print('Numerical features: ' + str(len(numerical_features)))\n",
    "    \n",
    "    df_num = df[numerical_features]\n",
    "    \n",
    "    # 用训练集里中值替换数值型特征中的缺失值\n",
    "    print('NAs for numerical features in df: ' + str(df_num.isnull().values.sum()))\n",
    "    df_num = df_num.fillna(medians)\n",
    "    print('Remaining NAs for numerical features in df: ' + str(df_num.isnull().values.sum()))\n",
    "    \n",
    "    # 对数值特征进行标准化\n",
    "    temp = ss_X.fit_transform(df_num)\n",
    "    df_num = pd.DataFrame(data=temp, columns=numerical_features, index=df_num.index)\n",
    "    \n",
    "    return df_num\n",
    "\n",
    "test_num = fillna_numerical_test(test, medians, ss_X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Categorical features in df: 48\n",
      "NAs for categorical features in df: 61286\n",
      "Remaining NAs for categorical features in df:0\n"
     ]
    }
   ],
   "source": [
    "def get_dummies_cat(df):\n",
    "    categorical_features = df.select_dtypes(include=['object']).columns\n",
    "    print('Categorical features in df: ' + str(len(categorical_features)))\n",
    "    df_cat = df[categorical_features]\n",
    "    \n",
    "    # 通过独热编码为类型值创建虚拟特征\n",
    "    print('NAs for categorical features in df: ' + str(df_cat.isnull().values.sum()))\n",
    "    df_cat = pd.get_dummies(df_cat, dummy_na=True)\n",
    "    print('Remaining NAs for categorical features in df:' + str(df_cat.isnull().values.sum()))\n",
    "    \n",
    "    return df_cat\n",
    "\n",
    "# 必须考虑类别型特征的取值范围(训练集和测试集的取值范围可能不同)\n",
    "n_train_samples = train.shape[0]\n",
    "train_test = pd.concat((train, test), axis=0)\n",
    "train_test_cat = get_dummies_cat(train_test)\n",
    "\n",
    "train_cat = train_test_cat.iloc[:n_train_samples, :]\n",
    "test_cat = train_test_cat.iloc[n_train_samples:, :]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 1459 entries, 0 to 1459\n",
      "Columns: 262 entries, BldgType_1Fam to SimplPoolScore_nan\n",
      "dtypes: uint8(262)\n",
      "memory usage: 384.7 KB\n"
     ]
    }
   ],
   "source": [
    "train_cat.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "New number of features: 357\n",
      "New number of features: 357\n"
     ]
    }
   ],
   "source": [
    "# 合并类别型和数值型特征\n",
    "def joint_num_cat(df_num, df_cat):\n",
    "    df = pd.concat([df_num, df_cat], axis=1, ignore_index=True)\n",
    "    print('New number of features: ' + str(df.shape[1]))\n",
    "    \n",
    "    return df\n",
    "\n",
    "FE_train = joint_num_cat(train_num, train_cat)\n",
    "FE_test = joint_num_cat(test_num, test_cat)\n",
    "\n",
    "FE_train = pd.concat([FE_train, train['SalePrice']], axis=1)\n",
    "FE_test = pd.concat([test_id, FE_test], axis=1)\n",
    "\n",
    "FE_train.to_csv('AmesHousePrices_FE_train.csv', index=False)\n",
    "FE_test.to_csv('AmesHouesePrices_FE_test.csv', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 1459 entries, 0 to 1459\n",
      "Columns: 358 entries, 0 to SalePrice\n",
      "dtypes: float64(95), int64(1), uint8(262)\n",
      "memory usage: 1.4 MB\n"
     ]
    }
   ],
   "source": [
    "FE_train.info()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
